#ifndef VECTOR3_H
#define VECTOR3_H

#include "Export.h"
#include <cmath>

namespace glow 
{
	template<class T>
    class SHARED Vector3
    {
		public :
		
		T x, y, z;
			
		Vector3(T x = 0, T y = 0, T z = 0) : x(x), y(y), z(z) {}
		
		 ~Vector3() {}

		Vector3(T i)
		{
			x = i;
			y = i;
			z = i;
		}
		
		Vector3(const Vector3<T> &v)
		{
			x = v.x;
			y = v.y;
			z = v.z;
		}

		Vector3(const Vector3<T> &from, const Vector3<T> &to)
		{
			x = to.x - from.x;
			y = to.y - from.y;
			z = to.z - from.z;
		}

		Vector3<T> &operator=(const Vector3<T> &v)
		{
			x = v.x;
			y = v.y;
			z = v.z;
			return *this;
		}

		Vector3<T> &operator+=(const Vector3<T> &v)
		{
			x += v.x;
			y += v.y;
			z += v.z;
			return *this;
		}

		Vector3<T> operator+(const Vector3<T> &v) const
		{
			Vector3 t = *this;
			t += v;
			return t;
		}

		Vector3<T> &operator-=(const Vector3<T> &v)
		{
			x -= v.x;
			y -= v.y;
			z -= v.z;
			return *this;
		}

		Vector3<T> operator-(const Vector3<T> &v) const
		{
			Vector3 t = *this;
			t -= v;
			return t;
		}

		Vector3<T> &operator*= (const T a)
		{
			x *= a;
			y *= a;
			z *= a;
			return *this;
		}

		Vector3<T> operator* (const T a)const
		{
			Vector3 t = *this;
			t *= a;
			return t;
		}

		Vector3<T> &operator/= (const T a)
		{
			x /= a;
			y /= a;
			z /= a;
			return *this;
		}

		Vector3<T> operator/ (const T a)const
		{
			Vector3 t = *this;
			t /= a;
			return t;
		}

		Vector3<T> crossProduct(const Vector3<T> &v)const
		{
			Vector3 t;
			t.x = y*v.z - z*v.y;
			t.y = z*v.x - x*v.z;
			t.z = x*v.y - y*v.x;
			return t;
		}

		T length()const
		{
			return sqrt(x*x + y*y + z*z);
		}

		Vector3<T> &normalize()
		{
			if(length() == 0)
				return (*this);
			else
			{
				(*this) /= length();
				return (*this);
			}
		}
	};
	  
  typedef Vector3<unsigned int> Vector3ui;
  /* unsigned bytes for colors, textures */
  typedef Vector3<unsigned char> Vector3ub; 
  typedef Vector3<int> Vector3i;
  typedef Vector3<float> Vector3f;
  typedef Vector3<double> Vector3d;
	
}

#endif
